//package org.example.Redis.Service.Impl;
//
//import com.beust.jcommander.internal.Lists;
//import com.fasterxml.jackson.core.type.TypeReference;
//import lombok.NoArgsConstructor;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang3.StringUtils;
//import org.example.Redis.Service.RedisService;
//import org.example.Redis.Utils.JsonUtil;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.dao.DataAccessException;
//import org.springframework.data.redis.connection.RedisConnection;
//import org.springframework.data.redis.connection.StringRedisConnection;
//import org.springframework.data.redis.core.*;
//import org.springframework.data.redis.core.types.RedisClientInfo;
//import org.springframework.data.redis.serializer.RedisSerializer;
//import org.springframework.stereotype.Service;
//import org.springframework.util.CollectionUtils;
//import redis.clients.jedis.Jedis;
//import redis.clients.jedis.JedisCluster;
//
//import javax.annotation.Resource;
//import java.util.*;
//import java.util.concurrent.TimeUnit;
//
///**
// * @Author : zhangbo
// * @data : 2024/7/4
// * @description :
// */
//@Slf4j
//@Service
//public class RedisServiceImpl implements RedisService {
//    private static Logger logger = LoggerFactory.getLogger(RedisServiceImpl.class);
//    @Resource
//    private static StringRedisTemplate redisTemplate;
//
//    public static void main(String[] args) {
//        //String
//        String key = "key_001";
//        String value = "myValue";
//        redisTemplate.opsForValue().set(key, value);
//        //list
//        List<String> values = Arrays.asList("value1", "value2");
//        redisTemplate.opsForList().rightPushAll("key_001", values);
//        //set
//        redisTemplate.opsForSet().add("key_001", "value1");
//        //sortset
//        redisTemplate.opsForZSet().add("key_001", "score1", 1.0);
//        //hash
//        Map<String, String> hash = new HashMap<>();
//        hash.put("field1", "value1");
//        redisTemplate.opsForHash().putAll("key_001", hash);
//
//        Set set = redisTemplate.opsForSet().members("key_001");
//    }
//
///*    public RedisServiceImpl(StringRedisTemplate redisTemplate) {
//        this.redisTemplate = redisTemplate;
//    }
//
//    public StringRedisTemplate getRedisTemplate() {
//        return redisTemplate;
//    }*/
//
//    @Override
//    public Object executeLua(String lua, List<String> keys, List<String> args) {
//        //spring自带的执行脚本方法中，集群模式直接抛出不支持执行脚本异常，此处拿到原redis的connection执行脚本
//        Object result = redisTemplate.execute(new RedisCallback() {
//            @Override
//            public Object doInRedis(RedisConnection connection) throws DataAccessException {
//                Object nativeConnection = connection.getNativeConnection();
//                // 集群模式和单点模式虽然执行脚本的方法一样，但是没有共同的接口，所以只能分开执行
//                // 集群
//                if (nativeConnection instanceof JedisCluster) {
//                    return ((JedisCluster) nativeConnection).eval(lua, keys, args);
//                }
//                // 单点
//                else if (nativeConnection instanceof Jedis) {
//                    return ((Jedis) nativeConnection).eval(lua, keys, args);
//                }
//                return null;
//            }
//        });
//        return result;
//    }
//
//    @Override
//    public Object put() {
//        //String
//        String key = "key_001";
//        String value = "myValue";
//        redisTemplate.opsForValue().set(key, value);
//        //list
//        List<String> values = Arrays.asList("value1", "value2");
//        redisTemplate.opsForList().rightPushAll("key_001", values);
//        //set
//        redisTemplate.opsForSet().add("key_001", "value1");
//        //sortset
//        redisTemplate.opsForZSet().add("key_001", "score1", 1.0);
//        //hash
//        Map<String, String> hash = new HashMap<>();
//        hash.put("field1", "value1");
//        redisTemplate.opsForHash().putAll("key_001", hash);
//
//        Set set = redisTemplate.opsForSet().members("key_001");
//        return set;
//    }
//
//    @Override
//    public void put(Map<String, Object> map) {
//        redisTemplate.execute(new RedisCallback<Object>() {
//            @Override
//            public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
//                return null;
//            }
//        });
//
//    }
//
//
//    @Override
//    public Object executeLuaSha(String sha, List<String> keys, List<String> args) {
//        //spring自带的执行脚本方法中，集群模式直接抛出不支持执行脚本异常，此处拿到原redis的connection执行脚本
//        Object result = redisTemplate.execute(new RedisCallback() {
//            @Override
//            public Object doInRedis(RedisConnection connection) throws DataAccessException {
//                Object nativeConnection = connection.getNativeConnection();
//                // 集群模式和单点模式虽然执行脚本的方法一样，但是没有共同的接口，所以只能分开执行
//                // 集群
//                if (nativeConnection instanceof JedisCluster) {
//                    return ((JedisCluster) nativeConnection).evalsha(sha, keys, args);
//                }
//                // 单点
//                else if (nativeConnection instanceof Jedis) {
//                    return ((Jedis) nativeConnection).evalsha(sha, keys, args);
//                }
//                return null;
//            }
//        });
//        return result;
//    }
//
//    @Override
//    public Object executeLoadLua(String luaScript) {
//        //spring自带的执行脚本方法中，集群模式直接抛出不支持执行脚本异常，此处拿到原redis的connection执行脚本
//        Object result = redisTemplate.execute(new RedisCallback() {
//            @Override
//            public Object doInRedis(RedisConnection connection) throws DataAccessException {
//                Object nativeConnection = connection.getNativeConnection();
//                return ((Jedis) nativeConnection).scriptLoad(luaScript);
//            }
//        });
//        return result;
//    }
//    @Override
//    public List<String> rangeList(String key) {
//        return redisTemplate.opsForList().range(key,0,-1);
//    }
//
//    /**
//     * 批量删除对应的value
//     *
//     * @param keys
//     */
//    @Override
//    public void remove(final String... keys) {
//        redisTemplate.delete(Lists.newArrayList(keys));
//    }
//
//
//    /**
//     * 删除对应的value
//     *
//     * @param key
//     */
//    @Override
//    public void remove(final String key) {
//        if (exists(key)) {
//            redisTemplate.delete(key);
//        }
//    }
//
//    @Override
//    public void removeByVague(String pattern) {
//        Set<String> keys = redisTemplate.keys(pattern);
//        if (!CollectionUtils.isEmpty(keys)) {
//            redisTemplate.delete(keys);
//        }
//    }
//
//    @Override
//    public void removeHashValue(String key, Object... hashKey){
//        if(exists(key)){
//            redisTemplate.boundHashOps(key).delete(hashKey);
//        }
//    }
//
//    /**
//     * 判断缓存中是否有对应的value
//     *
//     * @param key
//     * @return
//     */
//    @Override
//    public boolean exists(final String key) {
//        return redisTemplate.hasKey(key);
//    }
//
//    @Override
//    public boolean hExists(final String key) {
//        return redisTemplate.boundHashOps(key).hasKey(key);
//    }
//
//    /**
//     * 读取缓存
//     *
//     * @param key
//     * @return
//     */
//    @Override
//    public <T> T get(final String key, Class<T> cls) {
//        try {
//            String value = redisTemplate.boundValueOps(key).get();
//            if (StringUtils.isBlank(value)) {
//                return null;
//            }
//            return JsonUtil.getObjectMapper().readValue(value, cls);
//        } catch (Exception e) {
//            return null;
//        }
//    }
//
//    /**
//     * 读取缓存
//     *
//     * @param key
//     * @param cls
//     * @param <T>
//     * @return
//     */
//    @Override
//    public <T> T get(final String key, TypeReference<T> cls) {
//        try {
//            String value = redisTemplate.boundValueOps(key).get();
//            if (StringUtils.isBlank(value)) {
//                return null;
//            }
//            return JsonUtil.getObjectMapper().readValue(value, cls);
//        } catch (Exception e) {
//            return null;
//        }
//    }
//
//    /**
//     * 读取缓存
//     *
//     * @param key
//     * @return
//     */
//    @Override
//    public String getString(final String key) {
//        try {
//            return redisTemplate.boundValueOps(key).get();
//        } catch (Exception e) {
//            return null;
//        }
//    }
//
//    /**
//     * 写入缓存
//     *
//     * @param key
//     * @param value
//     * @return
//     */
//    @Override
//    public boolean setString(final String key, String value) {
//        boolean result = false;
//        try {
//            redisTemplate.boundValueOps(key).set(value);
//            result = true;
//        } catch (Exception e) {
//            logger.error("出错啦!", e);
//        }
//        return result;
//    }
//
//    @Override
//    public boolean setString(String key, String value, long expireSeconds) {
//        boolean result = false;
//        try {
//            redisTemplate.boundValueOps(key).set(value, expireSeconds, TimeUnit.SECONDS);
//            result = true;
//        } catch (Exception e) {
//            logger.error("出错啦!", e);
//        }
//        return result;
//    }
//
//    /**
//     * 写入缓存
//     *
//     * @param key
//     * @param value
//     * @return
//     */
//    @Override
//    public boolean set(final String key, Object value) {
//        boolean result = false;
//        try {
//            redisTemplate.boundValueOps(key).set(JsonUtil.getObjectMapper().writeValueAsString(value));
//            result = true;
//        } catch (Exception e) {
//            logger.error("出错啦!,{}", e);
//            List<RedisClientInfo> list = redisTemplate.getClientList();
//            for(RedisClientInfo r : list){
//                logger.error("获取redis链接ip", r.getAddressPort());
//            }
//        }
//        return result;
//    }
//
//    /**
//     * 写入缓存
//     *
//     * @param key
//     * @param value
//     * @param expireTime 单位秒
//     * @return
//     */
//    @Override
//    public boolean set(final String key, Object value, Long expireTime) {
//        boolean result = false;
//        try {
//            redisTemplate.boundValueOps(key).set(JsonUtil.getObjectMapper().writeValueAsString(value), expireTime, TimeUnit.SECONDS);
//            result = true;
//        } catch (Exception e) {
//            logger.error("出错啦!,{}", e);
//            List<RedisClientInfo> list = redisTemplate.getClientList();
//            for(RedisClientInfo r : list){
//                logger.error("获取redis链接ip", r.getAddressPort());
//            }
//        }
//        return result;
//    }
//
//    @Override
//    public Long remainTimeToLive(String key) {
//        if (exists(key)) {
//            return redisTemplate.boundValueOps(key).getExpire();
//        } else {
//            return -1L;
//        }
//    }
//
//    @Override
//    public Boolean expire(String key, Long expireTime, TimeUnit timeUnit) {
//        return redisTemplate.expire(key, expireTime, timeUnit);
//    }
//
//    @Override
//    public void expireAt(String key, Date date) {
//        byte[] rawKey =  rawKey(key);
//        redisTemplate.execute(new RedisCallback<Boolean>() {
//
//            @Override
//            public Boolean doInRedis(RedisConnection connection) {
//                return connection.expireAt(rawKey, date.getTime() / 1000);
//            }
//        }, true);
//
//    }
//
//    private byte[] rawKey(Object key) {
//        if (keySerializer() == null && key instanceof byte[]) {
//            return (byte[]) key;
//        }
//        return keySerializer().serialize(key);
//    }
//
//    private RedisSerializer keySerializer() {
//        return redisTemplate.getKeySerializer();
//    }
//
//
//    @Override
//    public boolean setNx(String key, Object value) {
//        boolean result = false;
//        try {
//            redisTemplate.boundValueOps(key).setIfAbsent(JsonUtil.getObjectMapper().writeValueAsString(value));
//            result = true;
//        } catch (Exception e) {
//            logger.error("出错啦!", e);
//        }
//        return result;
//    }
//
//    /**
//     * 命令将 key 中储存的数字值增一。
//     *
//     * @param key
//     * @return
//     */
//    @Override
//    public Long incr(String key) {
//        Long result = redisTemplate.execute((RedisCallback<Long>) redisConnection -> {
//            return redisConnection.incr(key.getBytes());
//        });
//        return result;
//    }
//
//    @Override
//    public Long incrBy(String key, long value) {
//        return redisTemplate.execute((RedisCallback<Long>) redisConnection -> redisConnection.incrBy(key.getBytes(), value));
//    }
//
//    @Override
//    public Long decr(String key) {
//        return redisTemplate.execute((RedisCallback<Long>) redisConnection -> redisConnection.decr(key.getBytes()));
//    }
//
//    @Override
//    public Long decrBy(String key, long value) {
//        return redisTemplate.execute((RedisCallback<Long>) redisConnection -> redisConnection.decrBy(key.getBytes(), value));
//    }
//
//    @Override
//    public Map getMap(String key) {
//        return redisTemplate.boundHashOps(key).entries();
//    }
//
//
//    /**
//     * 哈希添加数据
//     *
//     * @param key     key 值
//     * @param hashKey 哈希key
//     * @param value
//     */
//    @Override
//    public boolean addHashSet(String key, Object hashKey, Object value) {
//
//        boolean result = false;
//        try {
//            redisTemplate.boundHashOps(key).put(hashKey, value);
//            result = true;
//        } catch (Exception e) {
//            logger.error("出错啦!", e);
//        }
//        return result;
//    }
//
//    /**
//     * 批量插入hash表
//     * @param key key
//     * @param hashKeyAndValue hash表每一条记录的key and value
//     * @return
//     */
//    @Override
//    public boolean batchAddHashSet(String key, Map<String,String> hashKeyAndValue){
//        try{
//            redisTemplate.opsForHash().putAll(key,hashKeyAndValue);
//            //redisTemplate.executePipelined();  springboot1.5不支持管道 改用putAll
//            return true;
//        }catch (Exception e){
//            logger.error("批量插入hash出错",e);
//            return false;
//        }
//    }
//    /**
//     * 根据hashKey获取数据
//     *
//     * @param key     key 值
//     * @param hashKey 哈希key
//     * @return
//     */
//    @Override
//    public Object getHashSet(String key, Object hashKey) {
//        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
//        return hash.get(key, hashKey);
//    }
//
//    /**
//     * 根据指定hashKey值自增value(1,2,3,4...);
//     *
//     * @param key     key 值
//     * @param hashKey 哈希key
//     * @param value   起始值
//     * @return
//     */
//    @Override
//    public Long hincrBy(String key, Object hashKey, Long value) {
//        return redisTemplate.boundHashOps(key).increment(hashKey, value);
//    }
//
//    @Override
//    public Long delHashByKey(String key, Object hashKey) {
//        return redisTemplate.boundHashOps(key).delete(hashKey);
//    }
//
//    @Override
//    public Long hashSize(String key){
//        return redisTemplate.boundHashOps(key).size();
//    }
//
//    /**
//     * 集合添加数据
//     *
//     * @param key
//     * @param value
//     * @return
//     */
//    @Override
//    public boolean addSet(String key, String... value) {
//        boolean result = false;
//        try {
//            SetOperations<String, String> set = redisTemplate.opsForSet();
//            set.add(key, value);
//            result = true;
//        } catch (Exception e) {
//            logger.error("出错啦!", e);
//        }
//        return result;
//    }
//
//    /**
//     * 集合获取数据
//     *
//     * @param key
//     * @return
//     */
//    @Override
//    public Set<String> getSet(String key) {
//        SetOperations<String, String> set = redisTemplate.opsForSet();
//        return set.members(key);
//    }
//
//    @Override
//    public Long removeSetValue(String key, String... value) {
//        SetOperations<String, String> set = redisTemplate.opsForSet();
//        return set.remove(key,value);
//    }
//
//    /**
//     * 获取集合的大小
//     *
//     * @param key
//     * @return
//     */
//    @Override
//    public Long getSetSize(String key) {
//        SetOperations<String, String> set = redisTemplate.opsForSet();
//        return set.size(key);
//    }
//
//    /**
//     * 根据key值随机获取集合中一个值，得到该值之后并删除该值
//     *
//     * @param key
//     * @return
//     */
//    @Override
//    public String getOneSet(String key) {
//        SetOperations<String, String> set = redisTemplate.opsForSet();
//        return set.pop(key);
//    }
//
//    /**
//     * 将一个或多个值插入到列表头部
//     * @param key
//     * @param values
//     * @return
//     */
//    @Override
//    public Object lpush(String key, String... values){
//        return redisTemplate.execute(new RedisCallback() {
//            @Override
//            public Object doInRedis(RedisConnection connection) throws DataAccessException {
//                StringRedisConnection conn = (StringRedisConnection) connection;
//                conn.lPush(key, values);
//                return null;
//            }
//        });
//    }
//
//    /**
//     * 将一个或多个值插入到列表尾部
//     *
//     * @param key
//     * @param values
//     * @return
//     */
//    @Override
//    public Object rpush(String key, String... values) {
//        return redisTemplate.execute(new RedisCallback() {
//            @Override
//            public Object doInRedis(RedisConnection connection) throws DataAccessException {
//                StringRedisConnection conn = (StringRedisConnection) connection;
//                conn.rPush(key, values);
//                return null;
//            }
//        });
//    }
//
//    @Override
//    public Long lpushAll(String key, Collection<String> stringCollection, Date expireDate){
//        Long result=0L;
//        if(!CollectionUtils.isEmpty(stringCollection)){
//            result=redisTemplate.opsForList().leftPushAll(key,stringCollection);
//            this.expireAt(key,expireDate);
//        }
//        return result;
//    }
//
//    @Override
//    public Long rpushAll(String key, Collection<String> stringCollection, Long expireTime, TimeUnit timeUnit){
//        Long result=0L;
//        if(!CollectionUtils.isEmpty(stringCollection)){
//            result=redisTemplate.opsForList().rightPushAll(key,stringCollection);
//            this.expire(key,expireTime,timeUnit);
//        }
//        return result;
//    }
//
//    @Override
//    public List<String> rangeList(String key, Long start, Long end){
//        try{
//            return redisTemplate.opsForList().range(key,start,end);
//        }catch (Exception e){
//            logger.info("rangeList异常",e);
//            return null;
//        }
//    }
//
//    @Override
//    public Long listSize(String key){
//        try{
//            return redisTemplate.opsForList().size(key);
//        }catch (Exception e){
//            logger.info("listSize异常",e);
//            return 0L;
//        }
//    }
//
//    @Override
//    public String lpopOne(String key){
//        return redisTemplate.opsForList().leftPop(key);
//    }
//
//    @Override
//    public String lpopOneBlock(String key, long num, TimeUnit timeUnit) {
//        return redisTemplate.opsForList().leftPop(key, num, timeUnit);
//    }
//
//    @Override
//    public String rpopOne(String key){
//        return redisTemplate.opsForList().rightPop(key);
//    }
//
//    @Override
//    public String rpopOneBlock(String key, long num, TimeUnit timeUnit) {
//        return redisTemplate.opsForList().rightPop(key, num, timeUnit);
//    }
//
//    @Override
//    public String listIdx(String key, Long index){
//        return redisTemplate.opsForList().index(key,index);
//    }
//
//    /**
//     *
//     * @param key
//     * @return
//     */
//    @Override
//    public Long ttl(String key){
//        return (Long) redisTemplate.execute(new RedisCallback() {
//            @Override
//            public Object doInRedis(RedisConnection connection) throws DataAccessException {
//                StringRedisConnection conn = (StringRedisConnection) connection;
//                return conn.ttl(key, TimeUnit.SECONDS);
//            }
//        });
//    }
//
//    /**
//     * 防重锁
//     * @param key
//     * @return
//     */
//    @Override
//    public boolean repeatLock(String key) {
//        return this.repeatLock(key, 30L);
//    }
//
//    /**
//     * 防重锁
//     * @param key
//     * @param secends
//     * @return
//     */
//    @Override
//    public boolean repeatLock(String key, Long secends) {
//        boolean result = false;
//        if (this.incr(key) == 1) {
//            result = true;
//        }
//        this.expire(key, secends, TimeUnit.SECONDS);
//        return result;
//    }
//
//
//    @Override
//    public boolean repeatWaitCheck(String redisKey,Long sleepTime,Long expireTime,int circulate) {
//        int i = 0;
//        boolean result = true;
//        do {
//            if (this.incr(redisKey) != 1) {
//                try {
//                    Thread.sleep(sleepTime);
//                } catch (InterruptedException e) {
//                    log.error("repeatWaitCheck sleep error", e);
//                }
//                if(++i >= circulate) {
//                    result = false;
//                    break;
//                }
//                continue;
//            }
//            break;
//        } while (true);
//        this.expire(redisKey, expireTime, TimeUnit.SECONDS);
//        return result;
//    }
//
//
//    @Override
//    public boolean repeatWaitCheck(String redisKey){
//        return repeatWaitCheck(redisKey,100L,30L,50);
//    }
//
//
//    @Override
//    public Double zIncrBy(String zKey,Object sKey,Double score){
//        return redisTemplate.boundZSetOps(zKey).incrementScore(String.valueOf(sKey),score);
//    }
//
//    @Override
//    public Map<Object, Object> getHashSetAll(String key) {
//        return redisTemplate.boundHashOps(key).entries();
//    }
//
//    @Override
//    public Map<String, String> getHashSetAllStr(String key) {
//        BoundHashOperations<String, String, String> hashOperations = redisTemplate.boundHashOps(key);
//        return hashOperations.entries();
//    }
//
//
//
//
//    @Override
//    public Set<String> getRankKeyWithEnd(String key,Long end){
//        return redisTemplate.boundZSetOps(key).reverseRange(0, end);
//    }
//
//    @Override
//    public boolean existSet(String key, String member) {
//        return redisTemplate.boundSetOps(key).isMember(member);
//    }
//
//    @Override
//    public boolean zRemoveKey(String key, String zKey) {
//        redisTemplate.boundZSetOps(key).remove(zKey);
//        Long rank = redisTemplate.boundZSetOps(key).rank(zKey);
//        if (rank == null){
//            return true;
//        }else{
//            return false;
//        }
//    }
//
//    @Override
//    public boolean zExist(String key, String zKey) {
//        Long rank = redisTemplate.boundZSetOps(key).rank(zKey);
//        if (rank == null){
//            return false;
//        }else{
//            return true;
//        }
//    }
//
//    @Override
//    public boolean setBit(String key, long offset, boolean value) {
//        return redisTemplate.opsForValue().setBit(key,offset,value);
//    }
//
//    @Override
//    public Long countBit(String key) {
//        return redisTemplate.execute((RedisCallback<Long>) con -> con.bitCount(key.getBytes()));
//    }
//
//    @Override
//    public Long getExpire(String key) {
//        return redisTemplate.getExpire(key,TimeUnit.SECONDS);
//    }
//
//    @Override
//    public Object executeMultipleLua(String sha, String key, String opKey, String param) {
//        List<String> list = new ArrayList<>();
//        list.add(opKey);
//        if (param != null){
//            list.add(param);
//        }
//        return executeLuaSha(sha, Arrays.asList(key,opKey),list);
//    }
//
//    @Override
//    public Object executeSingleLua(String lua, String key, Object param) {
//        return executeLuaSha(lua, Arrays.asList(key),Collections.singletonList(JsonUtil.toJson(param)));
//    }
//}
